package com.google.appengine.api.images; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import org.imgscalr.Scalr; import org.imgscalr.Scalr.Mode; public class ImagesService { public enum OutputEncoding { JPEG, PNG, WEBP; } public Image applyTransform(Transform transform, Image image, OutputEncoding outputEncoding) { return applyTransform(transform, image, new OutputSettings(outputEncoding)); } public Image applyTransform(Transform transform, Image image, OutputSettings settings) { switch (transform.getType()) { case CROP: return this.crop(image, (int)transform.get("left"), (int)transform.get("top"), (int)transform.get("right"), (int)transform.get("bottom")); case ROTATE: return this.rotate(image, (int)transform.get("rotation")); case RESIZE: return this.resize(image, (int)transform.get("width"), (int)transform.get("height")); default: throw new UnsupportedOperationException("uknown transform type"); } } private Image resize(Image image, int width, int height) { Mode translationMode = Mode.AUTOMATIC; if (image.getWidth() < width && image.getHeight() < height) { return image; } else if (image.getWidth() < width) { translationMode = Mode.FIT_TO_HEIGHT; } else if (image.getHeight() < height) { translationMode = Mode.FIT_TO_WIDTH; } else { float wRatio = ((float)width / (float)image.getWidth()); float hRatio = ((float)height / (float)image.getHeight()); translationMode = wRatio < hRatio ? Mode.FIT_TO_WIDTH : Mode.FIT_TO_HEIGHT; } BufferedImage bufferedImage = Scalr.resize(image.getNativeImage(), translationMode, width, height, (BufferedImageOp)null); /* java.awt.Image scaledImage = image.getNativeImage().getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH); BufferedImage bufferedImage = new BufferedImage(width, height, image.getNativeImage().getType()); bufferedImage.getGraphics().drawImage(scaledImage, 0, 0 , null); */ return new Image(bufferedImage, image.getFormat()); } private Image crop(Image image, int left, int top, int right, int bottom) { BufferedImage croppedImage = image.getNativeImage().getSubimage(left, top, right, bottom); return new Image(croppedImage, image.getFormat()); } private Image rotate(Image image, int rotation) { BufferedImage rotatedImage = new BufferedImage((int)image.getHeight(), (int)image.getWidth(), image.getType()); Graphics2D graphics = null; try { graphics = (Graphics2D) rotatedImage.getGraphics(); graphics.rotate(Math.toRadians(rotation)); graphics.drawImage( image.getNativeImage(), rotation < 0 ? -rotatedImage.getHeight() : 0, rotation > 0 ? -rotatedImage.getWidth() : 0, null); return new Image(rotatedImage, image.getFormat()); } finally { if (null != graphics) { graphics.dispose(); } } } }